﻿using Microsoft.Extensions.DependencyInjection;
using Modules.System.User;
using PetaPoco;
using PmSoft;
using PmSoft.ApplicationContext;
using PmSoft.Caching;
using PmSoft.DBContext;
using PmSoft.Entity;
using PmSoft.Repositories;
using PmSoft.Utilities;
using static Modules.Project.ProjectConstants;

namespace Modules.Reports;

/// <summary>
/// 项目班组按天统计仓储
/// </summary>
[UseDI(ServiceLifetime.Scoped)]
public class ReportProjectGroupDaysRepository : Repository<ReportProjectGroupDays, DefaultDbContext>
{
    private readonly IApplicationContext applicationContext;

    public ReportProjectGroupDaysRepository(DefaultDbContext dbContext, IApplicationContext applicationContext) : base(dbContext, applicationContext)
    {
        this.applicationContext = applicationContext;
    }

    /// <summary>
    /// 获取指定日期没有生成报告的项目ID集合
    /// </summary>
    /// <param name="date">日期</param>
    /// <param name="limit"></param>
    /// <returns></returns>
    public IEnumerable<int> GetProjectIdsInNoUpdate(DateTime date, int limit = 100)
    {
        Sql sql = Sql.Builder.Select("p.project_id")
             .From("project AS p")
             .Where("p.is_deleted=0 AND prj_status<>@0", 项目状态.完工)
             .Where("NOT EXISTS (SELECT prgd.project_id FROM report_project_group_days AS prgd WHERE prgd.project_id=p.project_id AND DATEDIFF(date,@0)=0)", date)
             .Append($"LIMIT {limit}");
        return DbContext.FetchFirstColumn<int>(sql);
    }

    /// <summary>
    /// </summary>
    /// <param name="query"></param>
    /// <param name="pageIndex"></param>
    /// <param name="pageSize"></param>
    /// <returns></returns>
    public IPagedList<ReportProjectGroupDays> GetReportProjectDays(ReportProjectGroupDaysQuery query, int pageIndex, int pageSize)
    {
        Sql sql = Sql.Builder;
        sql.Select("id")
            .From("report_project_group_days ");

        #region 主管单位数据权限

        if (applicationContext.CurrentUser is IDeptUser deptUser && !deptUser.IsSuperAdministrator())
        {
            sql.InnerJoin("project as prj").On($"report_project_group_days.project_id=prj.project_id and prj.is_deleted=0 and prj.industry_type=@0 ", deptUser.IndustryType);
            if (deptUser.Level == AdministrativeLevel.City)
                sql.Append($" and prj.city_code={deptUser.CityCode}");
            if (deptUser.Level == AdministrativeLevel.Area)
                sql.Append($" and prj.area_code={deptUser.AreaCode}");
        }

        #endregion 主管单位数据权限

        if (query.StartTime.HasValue)
            sql.Where("report_project_group_days.date >= @0", query.StartTime.Value);
        if (query.EndTime.HasValue)
            sql.Where("report_project_group_days.date <= @0", query.EndTime.Value);

        if (query.ProjectId.HasValue)
            sql.Where("report_project_group_days.project_id = @0", query.ProjectId.Value);
        sql.OrderBy("report_project_group_days.id DESC");
        return GetPagingEntities(pageSize, pageIndex, sql);
    }

    /// <summary>
    /// </summary>
    /// <param name="query"></param>
    /// <returns></returns>
    public IEnumerable<ReportProjectGroupDays> GetReportProjectDays(ReportProjectGroupDaysQuery query)
    {
        Sql sql = Sql.Builder;
        sql.Select("id")
            .From("report_project_group_days ");

        #region 主管单位数据权限

        if (applicationContext.CurrentUser is IDeptUser deptUser && !deptUser.IsSuperAdministrator())
        {
            sql.InnerJoin("project as prj").On($"report_project_group_days.project_id=prj.project_id and prj.is_deleted=0 and prj.industry_type=@0 ", deptUser.IndustryType);
            if (deptUser.Level == AdministrativeLevel.City)
                sql.Append($" and prj.city_code={deptUser.CityCode}");
            if (deptUser.Level == AdministrativeLevel.Area)
                sql.Append($" and prj.area_code={deptUser.AreaCode}");
        }

        #endregion 主管单位数据权限

        if (query.StartTime.HasValue)
            sql.Where("date >= @0", query.StartTime.Value);
        if (query.EndTime.HasValue)
            sql.Where("date <= @0", query.EndTime.Value);

        if (query.ProjectId.HasValue)
            sql.Where("report_project_group_days.project_id = @0", query.ProjectId.Value);
        if (query.ProjectIds != null)
            sql.Where("report_project_group_days.project_id in (@0)", query.ProjectIds);
        return PopulateEntitiesByEntityIds(DbContext.FetchFirstColumn<int>(sql));
    }
}